# -*- coding: utf-8 -*-
print "Autor: Matthias Kehrberg"
print "Titel: Simulation des Sahel-Syndroms"
print "Advances Methods WS 11/12"

'''Import der Bibliotheken'''
import csv
import os
import sys
import matplotlib.pyplot as plt
from matplotlib.figure import SubplotParams

'''========================================================================='''
'''Niederschlag als mit csv-Reader als Liste einlesen'''

reader = csv.reader (open('Niederschlag.csv', 'rb'), delimiter = ";") 
"""
Als Reader wird die Datei Niederschlag eingelesen
"""

niederschlagslist =[]
"""
Durch die eckigen Klammern wird die Variable niderschlagsliste als Liste\
definiert
"""


for row in reader:
    niederschlagslist.append(row)

"""
Jede Reihe in der eingelesenen Datei reader wird in die Liste\
niederschlagsliste geschrieben
"""

'''========================================================================='''
'''Konstanten definieren'''

Nahrungsbedarf = 0.06
FlaecheBiomass = 0.02
Druck = 0.03
Niederschlagsrate = 0.5
Abnahmerate = 0.3
Geburtenrate = 0.02
Produktionsrate = 0.4


'''Startwerte für Treffen'''
Bevoelkerungsdruck = 0
Landnutzung = 0
Nahrung = 0
Intensivierung = 0
Verbrauch = 0
Geburten = 0
ProduktionBiomasse = 0
"""
Die Treffen werden in weiterem Verlauf berechnet. Da diese allerdings\
vorher schon benötigt werden, werden diese hier definiert und es wird\
der Wert 0 zugewiesen.
"""


'''========================================================================='''
'''Initialisierung der Klassen Biomasse, Bevoelkerung und Bodenqualität'''

class Biomasse():
    """
    Klasse zur Berrechnug der Biomasse
    """
    def __init__(self, Level, growthRate, decayRate, timeStep, timeRange):

        self.Level = [Level] # Die Funktion Level wird als Liste definiert
        self.growthRate = growthRate 
        self.decayRate = decayRate
        self.timeStep = timeStep
        self.timeRange = timeRange
        """
        Die timeRange bestimmt den Zeitraum über den die Berechnung\
        durchgeführt wird
        """
    def growth(self):

        return ProduktionBiomasse * self.timeStep
        """
        Die Zunahme errechnet sich aus der PrduktionBiomasse (siehe Unten)\
        mit dem timeStep multipliziert. Diese Berechnung wird an die Klasse\
        übergeben
        """    

    def decay(self):
        """
        Methode zur Berechnung der Abnahme der Biomasse
        """        

        return Verbrauch * self.timeStep
        """
        Berechnung der Abnahme der Biomasse mit dem Verzehr (siehe Unten)\
        und dem timeStep
        """
        

class Bevoelkerung():

   
    def __init__(self, Level, growthRate, decayRate, timeStep, timeRange):

        self.Level = [Level]
        self.growthRate = growthRate
        self.decayRate = decayRate
        self.timeStep = timeStep
        self.timeRange = timeRange
        """
        Funktionen der Klasse Bevoelkerung wie in der Klasse Biomasse
        """    

    def growth(self):
        """
        Methode zur Berechnung Zunahme der Bevoelkerung
        """       

        return self.timeStep * Geburten    
        """
        Berechnung der Zunahme der Bevoelkerung mit den Geburten (siehe Unten)\
        und dem timeStep
        """        
 
    def decay(self):
        """
        Methode zur Berechnung der Abnahme der Bevoelkerung
        """        
        
        return self.Level[len(self.Level)-1] * self.decayRate*self.timeStep  
        """
        Berechnung der Abnahme der Bevoelkerung mit dem Level mit der Abnahmerate\
        (siehe Festlegung der Startwerte) und dem timeStep. Die Funktion Level\
        wird hier wird in der Liste verwendet.
        """       
        
class Bodenqualitaet():
    """
    Klasse zu Berechnung der Bodenqualität
    """    
    def __init__(self, Level, growthRate, decayRate, timeStep, timeRange, capacity):

        self.Level = [Level]
        self.growthRate = growthRate
        self.decayRate = decayRate
        self.timeStep = timeStep
        self.timeRange = timeRange
        self.capacity = capacity
        """
        Funktionen der Klasse Bevoelkerung wie in der Klasse Biomasse und\
        und der Bevoelkerung. zusätzlich wird in dieser Klasse noch eine\
        Kapazität(capacity) verwendet.
        """       
        
    def growth(self):
        """
        Methode zur Berechnung der Zunahme der Bodenqualitaet mit Kapazitaets-\
        limt
        """        

        return ((self.capacity-self.Level[len(self.Level)-1])/self.capacity)\
               * Intensivierung*self.timeStep
        """
        Berechnung der Zunahme der Bodenqualitaet mit einem Kapazitätslimit\
        (wurde auf 100% festgelegt), der Intensivierung (siehe "Berechnung\
        der Treffen) und dem timeStep.
        """
        

    def decay(self):
        """
        Methode zur Berechnung der Abnahme der Bodenqualitaet
        """        
        return self.timeStep * Landnutzung
        """
        Berechnung der Abnahme der Bodenqualitaet mit der Landnutzung\
        (siehe "Berechnung der Treffen") und dem timeStep
        """        



'''========================================================================'''
'''Festlegung der Startwerte fuer die Klassen'''

biomassPop = Biomasse(5,1,1,0.007812,30)
bevPop = Bevoelkerung(10,1,0.03,0.007812,30)
boquPop = Bodenqualitaet(20,1,1,0.007812,30,100)
"""
Die Klassen Biomasse, Bevoelkerung und Bodenqualitaet werden mit den\
Startwerten für Level, growthRate, decayRate, timeStep und timeRange\
als biomassPop, bevPop und boquPop für die weitere Verwendung umbenannt\
"""


'''========================================================================='''
'''Berechnung der Treffen'''

niederschlaghelp = [] #Eine Liste niederschlaghelp wirde erstellt
i = 0
while i < boquPop.timeRange/boquPop.timeStep:


    niederschlag = float (niederschlagslist [0] [i])
    niederschlaghelp.append (niederschlag)
    """
    Der niederschlag wird aus der niederschlagslist in der Länge von der\
    Stelle 0 bis zur Stelle des Zaehlers i als float definiert und in die\
    Liste niederschlagshelp geschrieben
    """ 
    
    boquPopSim = boquPop.Level[len(boquPop.Level)-1] + boquPop.growth()\
                 - boquPop.decay()
    biomassPopSim = biomassPop.Level[len(biomassPop.Level)-1] + \
                    biomassPop.growth()- biomassPop.decay()
    bevPopSim = bevPop.Level[len(bevPop.Level)-1] + bevPop.growth()\


    Nahrung = biomassPopSim * bevPopSim * Nahrungsbedarf 
    Landnutzung = boquPopSim * biomassPopSim * FlaecheBiomass 
    Bevoelkerungsdruck = (bevPopSim * boquPopSim * Druck) + 1
    Intensivierung = (1/Bevoelkerungsdruck) * (niederschlag * Niederschlagsrate) 
    Verbrauch = Nahrung * Abnahmerate
    Geburten = Nahrung * Geburtenrate
    ProduktionBiomasse = Produktionsrate * Landnutzung
    """
    Im oberen Block wird das Level für Bodenqualitaet. Biomasse und\
    Bevoelkerung mit den Methoden growth und decay der jeweiligen Klassen\
    berrechnet und ausgegeben.
    Im naechstenBlock werden die oben aufgefuehrten Treffen mit Hilfe von\
    Konstanten und Methoden berrechnet. 
    """
    
    
    bevPop.Level.append(bevPopSim)
    boquPop.Level.append(boquPopSim)
    biomassPop.Level.append(biomassPopSim)
    """
    Die errechnet Werte bevPopSim usw. werden in die Liste bevPop.Level usw.\
    geschrieben, die für die Berechnung der Methoden verwendet wird.
    """
    
    
    i = i + 1
    """
    Die Codezeilen in der while-Schleife werden solange durchgeführt, wie der\
    Zaehler i kleiner ist als die timeRange durch den timeStep dividiert.\
    Dies ist die Anzahl der Schritte für welche die Berechnung durchgeführt\
    wird.
    Nachdem die while-Schleife durchgelaufen ist wird der Zaehler i um\
    erhöht und die Berechnung läuft mit für die nächsten Werte durch
    """
    
'''========================================================================='''
'''Printbefehle'''

print "======================Start der Simulation==========================="
print " "

i=0
"""while i < boquPop.timeRange/boquPop.timeStep:
    print "year", i*boquPop.timeStep, "Boden", boquPop.Level[i],"Bevoelkerung"\
    , bevPop.Level[i], "Biomasse", biomassPop.Level[i]

    i = i + 1"""

print " "
print "======================Ende der Simulation============================"
"""
Nach dem selben Prinzip wie der while-Schleife oben werden hier die\
einzelnen Werte gedruckt
"""

'''========================================================================='''
'''Visualisierung'''

def darstellung(ax, fontsize=12):
    """Methode zur Darstellung der Ergebnisse"""

    ax1.plot(bevPop.Level)
    ax1.set_xlabel('Jahre', fontsize=12)
    ax1.set_xticks((1280,2560,3840))
    labelsx=ax1.set_xticklabels(("10","20","30"))
    ax1.set_ylabel('Population (Anzahl)', fontsize=12)
    ax1.set_title('Population', fontsize=12)
    """
    Dieser Plot stellt die Bevoelkerung dar. Auf der x-Achse sind die\
    Zeitschritte aufgtragen. Diese werden durch die Jahre ersetzt. Auf der\
    y-Achse ist die Beveolkerungsanzahl aufgetragen
    """

    ax2.plot(biomassPop.Level)
    ax2.set_xlabel('Jahre', fontsize=12)
    ax2.set_xticks((1280,2560,3840))
    labelsx=ax2.set_xticklabels(("10","20","30"))
    ax2.set_ylabel('Biomasse(t)', fontsize=12)
    ax2.set_title('Biomasse', fontsize=12)
    """
    Dieser Plot stellt, anch dem selben Schema wie oben die Biomasse dar.
    """
    
    ax3.plot(boquPop.Level)
    ax3.set_xlabel('Jahre', fontsize=12)
    ax3.set_xticks((1280,2560,3840))
    labelsx=ax3.set_xticklabels(("10","20","30"))
    ax3.set_ylabel('Bodenqualitaet (%)', fontsize=12)
    ax3.set_title('Bodenqualitaet', fontsize=12)
    """
    Dieser Plot stellt, anch dem selben Schema wie oben die Bodenqualitaet dar.
    """

    ax4.plot(niederschlaghelp)
    ax4.set_xlabel('Jahre', fontsize=12)
    ax4.set_xticks((1280,2560,3840))
    labelsx=ax4.set_xticklabels(("10","20","30"))
    ax4.set_ylabel('Niederschlag (mm)', fontsize=12)
    ax4.set_title('Niederschlag', fontsize=12)
    """
    Dieser Plot stellt, anch dem selben Schema wie oben den Niederschlag dar.
    """
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2)
"""
Die 4 Plots werden in zwei Reihen und zwei Spalten dargestellt, wobei sich die\
Plots ax1 und ax2 in der ersten Reihe und die Plots ax3 und ax4 in der zweiten\
befinden.
"""
darstellung(ax1)
darstellung(ax2)
darstellung(ax3)
darstellung(ax4)

plt.tight_layout()



plt.show()
plt.close('all')
